package cn.hflycolin;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

public class LexicalAnalysis {
	private String inputFile;
	private String outputFile;
	private String file;
	private int current;

	public LexicalAnalysis(String inputFile, String outputFile)
			throws IOException {
		file = "";
		current = 0;
		this.inputFile = inputFile;
		this.outputFile = outputFile;
		FileWriter eraseFile = null;
		eraseFile = new FileWriter(outputFile, false);
		eraseFile.write("");
	}

	public void analyze() throws IOException, InterruptedException {
		System.out.print("LexicalAnalyzing");
		for (int i = 0; i < 7; i++) {
			System.out.print(".");
			Thread.sleep(70);
		}
		readFile();
		int local;
		local = current;
		String temp = "";
		while (file.charAt(current) != '`') {
			if ((file.charAt(current) <= 'Z' && file.charAt(current) >= 'A')
					|| (file.charAt(current) <= 'z' && file.charAt(current) >= 'a')) {
				while ((file.charAt(current) <= 'Z' && file.charAt(current) >= 'A')
						|| (file.charAt(current) <= 'z' && file.charAt(current) >= 'a')) {
					temp = temp + file.charAt(current++);
				}
				no2(temp);
				temp = "";
			} else if (file.charAt(current) <= '9'
					&& file.charAt(current) >= '0') {
				while (file.charAt(current) <= '9'
						&& file.charAt(current) >= '0') {
					temp = temp + file.charAt(current++);
				}
				no3(temp);
				temp = "";
			} else if (file.charAt(current) == '>'
					&& file.charAt(current + 1) == '=') {
				wf(stringFill(">=", 16, ' ', true) + " 16");
				current = current + 2;
			} else if (file.charAt(current) == '<'
					&& file.charAt(current + 1) == '=') {
				wf(stringFill("<=", 16, ' ', true) + " 14");
				current = current + 2;
			} else if (file.charAt(current) == '<'
					&& file.charAt(current + 1) == '>') {
				wf(stringFill("<>", 16, ' ', true) + " 13");
				current = current + 2;
			} else if (file.charAt(current) == '>') {
				wf(stringFill(">", 16, ' ', true) + " 17");
				current++;
			} else if (file.charAt(current) == '<') {
				wf(stringFill("<", 16, ' ', true) + " 15");
				current++;
			} else if (file.charAt(current) == '=') {
				wf(stringFill("=", 16, ' ', true) + " 12");
				current++;
			} else if (file.charAt(current) == '-') {
				wf(stringFill("-", 16, ' ', true) + " 18");
				current++;
			} else if (file.charAt(current) == '*') {
				wf(stringFill("*", 16, ' ', true) + " 19");
				current++;
			} else if (file.charAt(current) == '(') {
				wf(stringFill("(", 16, ' ', true) + " 21");
				current++;
			} else if (file.charAt(current) == ')') {
				wf(stringFill(")", 16, ' ', true) + " 22");
				current++;
			} else if (file.charAt(current) == ':'
					&& file.charAt(current + 1) == '=') {
				wf(stringFill(":=", 16, ' ', true) + " 20");
				current = current + 2;
			} else if (file.charAt(current) == ';') {
				wf(stringFill(";", 16, ' ', true) + " 23");
				current++;
			} else if (file.charAt(current) == '~') {
				wf(stringFill("eoln", 16, ' ', true) + " 24");
				current++;
			} else if (file.charAt(current) == '`') {
				wf(stringFill("eof", 16, ' ', true) + " 25");
				current++;
			}else if(file.charAt(current) == ' '){
				current++;
			}else{
				System.out.println("LexicalAnalysis ERROR at \""+file.charAt(current)+"\"");
				System.exit(1);
			}
			temp = "";
		}
		System.out.println("\nLexicalAnalysis has done!");

	}

	private void no2(String temp) throws IOException {
		if (temp.equals("begin")) {
			wf(stringFill("begin", 16, ' ', true) + " 01");
		} else if (temp.equals("end")) {
			wf(stringFill("end", 16, ' ', true) + " 02");
		} else if (temp.equals("integer")) {
			wf(stringFill("integer", 16, ' ', true) + " 03");
		} else if (temp.equals("if")) {
			wf(stringFill("if", 16, ' ', true) + " 04");
		} else if (temp.equals("then")) {
			wf(stringFill("then", 16, ' ', true) + " 05");
		} else if (temp.equals("else")) {
			wf(stringFill("else", 16, ' ', true) + " 06");
		} else if (temp.equals("function")) {
			wf(stringFill("function", 16, ' ', true) + " 07");
		} else if (temp.equals("read")) {
			wf(stringFill("read", 16, ' ', true) + " 08");
		} else if (temp.equals("write")) {
			wf(stringFill("write", 16, ' ', true) + " 09");
		} else {
			wf(stringFill(temp, 16, ' ', true) + " 10");
		}
	}

	private void no3(String temp) throws IOException {
		wf(stringFill(temp, 16, ' ', true) + " 10");
	}

	private void readFile() throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				new FileInputStream(this.inputFile)));
		String temp = null;
		while ((temp = reader.readLine()) != null) {
			file = file + temp + "~";
		}
		file = file + "`";
	}

	private void wf(String context) throws IOException {
		FileWriter writer = new FileWriter(outputFile, true);
		writer.write(context + "\r\n");
		writer.close();
	}

	public String stringFill(String source, int fillLength, char fillChar,
			boolean isLeftFill) {
		if (source == null || source.length() >= fillLength)
			return source;
		StringBuilder result = new StringBuilder(fillLength);
		int len = fillLength - source.length();
		if (isLeftFill) {
			for (; len > 0; len--) {
				result.append(fillChar);
			}
			result.append(source);
		} else {
			result.append(source);
			for (; len > 0; len--) {
				result.append(fillChar);
			}
		}
		return result.toString();
	}
}
